import { getAppChanges, shouldBeActive } from '../application/app.helpers.js';
import { toLoadPromise } from '../lifecycles/load.js';
import { toUnmountPromise } from '../lifecycles/unmount.js';
import { toMountPromise } from '../lifecycles/mount.js';
import { toBootstrapPromise } from '../lifecycles/bootstrap.js';
import './navigation-event.js'
import { callCaptureEventListeners } from './navigation-event.js';

import { started } from '../start.js';

export function reroute(event) {

    // 确定哪些应用需要被 加载 挂载 卸载  
    const { appsToLoad, appsToMount, appsToUnmount } = getAppChanges();


    if (started) {
        // 用户调用了start 我们需要处理当前应用的挂载或者卸载
        return performAppchanges()
    }

    // 加载完毕后需要被挂载的
    loadApp()

    function loadApp() {
        // 这里的这个map 是在主线程上按照顺序执行的 ,并且主线任务执行完毕 才会执行里面的微任务
        return Promise.all(appsToLoad.map(app => toLoadPromise(app))).then(callEventListener)
    }


    function performAppchanges() {
        // 卸载不需要的应用
        const unmountAllPromise = Promise.all(appsToUnmount.map(toUnmountPromise))

        // 加载需要的应用->启动对应的应用->挂载对应的应用
        // 加载需要的应用 (可能这个应用在注册的时候,已经加载了)
        // 默认情况注册的时候 路径是/a 但是当我们start 的时候 路径是/b

        const loadMountPromise = Promise.all(appsToLoad.map(app => toLoadPromise(app).then((app) => {
            // 让它挂载之前 保证卸载完毕旧的应用
            // 尝试启动应用
            return trybootstrapAndMount(app, unmountAllPromise)
        })))

        // 如果应用没有加载 加载-> 启动 -> 挂载 
        // 如果应用已经加载了 直接启动 -> 挂载
        const MountPromise = Promise.all(appsToMount.map(app => trybootstrapAndMount(app, unmountAllPromise)))



        function trybootstrapAndMount(app, unmountAllPromise) {
            if (shouldBeActive(app)) {

                // 保证卸载完毕再挂载
                // 启动
                return toBootstrapPromise(app).then((app) => {
                  return  unmountAllPromise.then(() => {
                        // 挂载
                        toMountPromise(app)
                    })
                })
            }
        }

        return Promise.all([loadMountPromise,MountPromise]).then(() => {
            // 挂载完成
            callEventListener()
        })



    }


    function callEventListener() {
        callCaptureEventListeners(event);
    }



}